/*
  1.Promise就是一个类，在执行这个类的时候需要传递一个执行器（即传入的回调函数）进去，执行器会立即执行
  2.Promise中有三种状态，分别为成功fulfilled、失败rejected、等待pending,一旦状态确定就不可更改
  3.resolve和reject函数是用来更改状态的，resolve=>fulfilled   reject=>rejected
  4.then方法内部做的事情就是判断状态，如果状态是成功则调用成功的回掉函数，如果状态是失败则调用失败的回调函数
    then方法是被定义在原型对象中的
  5.then成功回调有一个参数，表示成功之后的值   then失败回调有一个参数，表示失败的原因
  6.then方法是可以被链式调用的，后面then方法的回调函数拿到的值是上一个then方法的回调函数的返回值
*/

// new Promise((resolve, reject) => {
//   resolve('成功')
//   reject('失败')
// })
// promise.then()

//定义常量为了可以复用和编辑器提示（偷懒）
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
  constructor(executor) {
    executor(this.resolve, this.reject)
  }

  //状态
  status = PENDING
  //成功之后的值
  value = undefined
  //失败的原因
  reason = undefined
  //成功回调
  successCallback = []
  //失败回调
  failCallback = []

  //为了使resolve和reject内部的this指向MyPromise所以使用箭头函数
  resolve = value => {
    if (this.status !== PENDING) return;
    this.status = FULFILLED
    //保存成功之后的值
    this.value = value
    //判断成功回调是否存在，如果存在就调用，但是多次调用不适用
    // this.successCallback && this.successCallback(this.value)

    //多次调用
    while(this.successCallback.length) this.successCallback.shift()(this.value)
  }
  reject = reason => {
    if (this.status !== PENDING) return;
    this.status = REJECTED
    //保存失败的原因
    this.reason = reason
    //判断失败的回调是否存在，如果存在就调用
    // this.failCallback && this.failCallback(this.reason)

    while(this.failCallback.length) this.failCallback.shift()(this.reason)
  }
  then(successCallback, failCallback) {
    // 判断状态
    if (this.status === FULFILLED) {
      successCallback(this.value)
    } else if (this.status === REJECTED) {
      failCallback(this.reason)
    } else {
      // 等待
      // 将成功回调和失败回调存储起来
      this.successCallback.push(successCallback)
      this.failCallback.push(failCallback)
    }
  }
}

let promise = new MyPromise((resolve, reject) => {
  // setTimeout(() => {
  //   resolve('成功')
  // }, 1000);
  // resolve('成功')
  reject('失败')
})
promise.then(value => {
  console.log(value)
})
// promise.then(value => {
//   console.log(2)
// })
// promise.then(value => {
//   console.log(3)
// })